package com.example.othree.service.impl;

import com.example.othree.common.DataUtil;
import com.example.othree.entity.InterfaceData;
import com.example.othree.mapper.InterfaceDataMapper;
import com.example.othree.service.AbnormalAlarmsService;
import com.example.othree.service.ScheduledTaskService;
import lombok.Getter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestTemplate;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
public class ScheduledTaskServiceImpl implements ScheduledTaskService {

    Logger logger = LoggerFactory.getLogger(getClass());

    @Autowired
    AbnormalAlarmsService abnormalAlarmsService;

    @Autowired
    InterfaceDataMapper interfaceDataMapper;

    @Value("${data.baseUrl}") String baseUrl;
    @Value("${data.managerEmail}") String emailForManager;

    @Getter
    private static boolean controllerState = true;

    private ArrayList<String> urls= new ArrayList<>();


    @Autowired
    RestTemplate restTemplate;

    @Autowired
    DataUtil dataUtil;

    @Override
    @Scheduled(cron = "0 */10 * * * *")
    public void periodicNonitor() {
        String currentTime = dataUtil.getTimeNew();
        boolean controllerState = true;

        List<InterfaceData> interfaceList = interfaceDataMapper.selectList(null);
        for (InterfaceData i :
                interfaceList) {
            boolean boolUrl = false;

            String url = null;
            if (i.getTestData().isEmpty()){
                url = (baseUrl + i.getUrl());
                boolUrl = checkInterfaceAccessibility(url);
            }else {
                String[] dataBody = i.getTestData().split("\\?");
                if ("param".equals(dataBody[0])){

                    url = (baseUrl + i.getUrl() + "?" + dataBody[1]);
                    boolUrl = checkInterfaceAccessibility(url);

                }else if ("body".equals(dataBody[0])){
                    System.out.println(i.getTestData());
                    // 创建请求体
                    String[] data = dataBody[1].split("&");

                    Map<String, Object> body = parseString(dataBody[1]);

                    url = (baseUrl + i.getUrl());


                    boolUrl = checkInterfaceAccessibility(url, body);
                }

            }

            if (boolUrl){
                i.setState("true");
                logger.info(currentTime + "---"  + url + "---" + "OK");
            }else {
                i.setState("false");
                logger.info(currentTime + "---"  + url + "---" + "No");
                abnormalAlarmsService.abnormalAlarmsEmail(emailForManager, "错误", "接口错误，可以联系管理员进行处理。");
                controllerState = false;
            }
            interfaceDataMapper.updateById(i);
        }

        this.controllerState = controllerState;
    }

    private boolean checkInterfaceAccessibility(String url) {
        try {
            // 这里假设接口返回的是JSON格式的响应
            // 根据实际情况，您可以检查响应中的特定字段或状态码来确定接口是否可访问
            Map<String, Object> response = restTemplate.getForObject(url, Map.class);
            if(response.get("code").equals(Integer.valueOf(20000))) {
                return true;
            }
            else {
                return false;
            }
            // 这里简单假设如果响应不为空，则接口可访问
        } catch (Exception e) {
            // 如果发生异常，则记录错误信息并返回false表示接口不可访问
            // 您可以将错误信息记录到日志中或使用其他方式进行记录
            System.err.println("Error checking interface accessibility for URL: " + url + ". Exception: " + e.getMessage());
            return false;
        }
    }

    private boolean checkInterfaceAccessibility(String url, Map<String, Object> body) {
        try {
            // 这里假设接口返回的是JSON格式的响应

            HttpHeaders headers = new HttpHeaders();
            headers.setContentType(MediaType.APPLICATION_JSON);

            // 创建HttpEntity对象
            HttpEntity<Map<String, Object>> request = new HttpEntity<>(body, headers);


            // 根据实际情况，您可以检查响应中的特定字段或状态码来确定接口是否可访问
            Map<String, Object> response = restTemplate.postForObject(url, request, Map.class);
            if(response.get("code").equals(Integer.valueOf(20000))) {
                return true;
            }
            else {
                return false;
            }
            // 这里简单假设如果响应不为空，则接口可访问
        } catch (Exception e) {
            // 如果发生异常，则记录错误信息并返回false表示接口不可访问
            // 您可以将错误信息记录到日志中或使用其他方式进行记录
            System.err.println("Error checking interface accessibility for URL: " + url + ". Exception: " + e.getMessage());
            return false;
        }
    }

    public Map<String, Object> parseString(String str) {
        Map<String, Object> map = new HashMap<>();

        List<String> parts = splitString(str);

        for (String pair : parts) {
            int equalsIndex = pair.indexOf("=");
            String key = pair.substring(0, equalsIndex);
            String value = pair.substring(equalsIndex + 1);
            // 检查值是否为嵌套的HashMap
            if (value.startsWith("{") && value.endsWith("}")) {
                // 递归解析嵌套的HashMap
                map.put(key, parseString(value.substring(1, value.length() - 1)));
            } else {
                // 直接存储值
                map.put(key, value);
            }
        }
        return map;
    }
    public  List<String> splitString(String input) {
        List<String> result = new ArrayList<>();
        StringBuilder current = new StringBuilder();
        int balance = 0; // 用于跟踪{}的平衡

        for (int i = 0; i < input.length(); i++) {
            char c = input.charAt(i);

            if (c == '{') {
                balance++;
                current.append(c);
            } else if (c == '}') {
                balance--;
                current.append(c);
            } else if (c == '&' && balance == 0) {
                // 当前字符是&且不在{}内部，分割字符串
                result.add(current.toString());
                current = new StringBuilder();
            } else {
                current.append(c);
            }
        }

        // 添加最后一个部分
        if (current.length() > 0) {
            result.add(current.toString());
        }

        return result;
    }

}
